<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<html>
<head>
	<title>XML-RPC Message Builder</title>
  
  <style type="text/css">
  .code {
    font-family:courier,monospace;
    font-size:12px;
  }
  body,td {
    font-family: verdana;
    font-size:12px;
  }
  h2 {
    border-bottom:1px solid #c0c0c0;
  }
  </style>
  
</head>

<body>
<p><a href="http://www.scottandrew.com">s c o t t a n d r e w . c o m</a></p>
<p><i>Last updated: 08/20/2001</i></p>

<h2>What is this?</h2>
<p>It's an XML-RPC message builder, written in JavaScript.  It takes JavaScript data objects and converts them into an XML-RPC message.</p>
<p>There are actually two components available here.  One is the message builder, the other a PHP gateway called <strong>xmlrpc-socket</strong> that forwards XML-RPC requests to remote servers over the Internet. Together they turn your browser into an XML-RPC client.</p>

<p>You can see a live demo of it <a href="test-rs.html">here</a>.</p>

<p>Download the library <a href="#rpc-download">here</a>.</p>

<p>You can read more about the XML-RPC specification <a href="http://www.xmlrpc.com">here</a>.</p>

<p><a href="mailto:xmlrpc@scottandrew.com">Comments?</a></p>

<p>
<ol>
<li><a href="#rpc-create">Creating an XML-RPC Message</a></li>
<ol type="A">
<li><a href="#rpc-methods">Object Methods</a></li>
<li><a href="#rpc-dtypes">Supported Data Types</a></li>
</ol>
<li><a href="#rpc-sample">A Sample XML-RPC Message</a></li>
<li><a href="#rpc-use">Making the Procedure Call</a></li>
<ol type="A">
<li><a href="#rpc-socket">Using xmlrpc-socket</a></li>
</ol>
<li><a href="#rpc-download">Download</a></li>
</ol>
</p>

<a name="rpc-create"></a>
<h2>Creating an XML-RPC Message</h2>

<p>First, create a new instance of the XMLRPCMessage object. The syntax is:</p>

<p><code>var msg = new XMLRPCMessage([string methodName]);</code></p>

<p><code>methodName</code> is the name of the method you wish to call on the remote server.  This parameter is optional.  If left out, the default requested method is <code>system.listMethods</code></p>

<a name="rpc-methods"></a>
<h3>Object Methods</h3>
<p>The XMLRPCMessage object has three methods:</p>

<table cellspacing="0" cellpadding="4" border="1" width="600">
<tr>
    <td class="code" valign="top">void addParameter(object variant)</td>
    <td valign="top">Accepts a JavaScript data type and adds a matching XML-RPC data type to the message</td>
</tr>
<tr>
    <td class="code" valign="top">void setMethod(string methodName)</td>
    <td valign="top">Declares the XML-RPC method you wish to call on the remote server.  You only need to use this if you haven't specified a method name when creating the XMLRPCMessage object.</td>
</tr>
<tr>
    <td class="code" valign="top">string xml()</td>
    <td valign="top">Returns a string of XML containing the message contents.</td>
</tr>
</table>
<h3>Supported Data Types</h3>
<a name="rpc-dtypes"></a>
<p>The XMLRPCMessage object is designed to take any JavaScript data type and convert it into the proper XML-RPC data type.  Simply pass the JS data thingy to the <code>addParameter</code> method and it will be converted to the proper format and value.</p>

<p>The following data types are supported:</p>

<table cellspacing="0" cellpadding="6" border="1" width="600">
<tr>
    <th>JavaScript Data Type</th>
    <th>Example</th>
    <th>XML-RPC equivalent</th>
    <th>Notes</th>
</tr>
<tr>
    <td>Boolean</td>
    <td>true</td>
    <td><xmp><boolean>1</boolean></xmp></td>
    <td>&nbsp;</td>
</tr>
<tr>
    <td>four-byte signed integer</td>
    <td>7</td>
    <td><xmp><i4>7</i4></xmp></td>
    <td>&nbsp;</td>
</tr>
<tr>
    <td>double-precision signed floating point number</td>
    <td>-3.14</td>
    <td><xmp><double>-3.14</double></xmp></td>
    <td>The script automagically determines whether a number is an integer or double.</td>
</tr>
<tr>
    <td>string</td>
    <td><xmp>"scottandrew"</xmp></td>
    <td>
<xmp>
<string>
 scottandrew
</string>
</xmp></td>
    <td>&nbsp;</td>
</tr>
<tr>
    <td>Date object</td>
    <td><xmp>d = new Date();</xmp></td>
    <td>
<xmp>
<dateTime.iso8601>
 20010716T18:16:18
</dateTime.iso8601>
</xmp></td>
    <td>Date objects are automatically converted into the ISO8601 format. You cannot pass date strings here; those will remain strings. Instead create a new Date object and use that.</td>
</tr>
<tr>
    <td>array</td>
    <td>
<xmp>
a = [
 "one",
 "two",
 "three"
];</xmp></td>
    <td>
<xmp>
<array>
 <data>
  <value>
   <string>one</string>
  </value>
  <value>
   <string>two</string>
  </value>
  <value>
   <string>three</string>
  </value>
 </data>
</array>
</xmp></td>
    <td rowspan="2">You don't have to worry if an Array or Object has a variety of data types as members; the script identifies the data type of each member and includes it in the message.<br /><br />Both arrays and structs can contain other arrays and structs as members, so it's possible to take a complex Object and describe it in XML by passing it to addParameter (this recursive feature is still being tested, though).</td>
</tr>

<tr>
    <td>object</td>
    <td>
<xmp>
obj = new Object();
obj.a = "hello";
obj.b = 7.22;
obj.c = 100;
</xmp></td>
    <td>
<xmp>
<struct>
 <member>
  <name>a</name>
  <value>
   <string>hello</string>
  </value>
 </member>
 <member>
  <name>b</name>
  <value>
   <double>7.22</double>
  </value>
 </member>
 <member>
  <name>c</name>
  <value>
   <i4>100</i4>
  </value>
 </member>
</struct>
</xmp></td>
</tr>
</table>

<p>This library does not currently support the base64 data type.</p>

<a name="rpc-sample"></a>
<h2>A Sample Message</h2>
<p>Here is an example of using the XMLRPCMessage object to create a message:</p>
<p><pre>
var a = ["chicken","duck","goose"];

var obj = new Object();
obj.x = 20;
obj.y = "cow";
obj.z = 3.14;

var date = new Date();

var msg = new XMLRPCMessage("system.myMethod");
msg.addParameter("mississippi");
msg.addParameter(7);
msg.addParameter(false);
msg.addParameter(a);
msg.addParameter(obj);
msg.addParameter(date);
</pre>
</p>
<p>This will create the following XML-RPC message:</p>
<p>
<xmp>
<?xml version="1.0"?>
<methodCall>
 <methodName>system.myMethod</methodName>
 <params>
   <param>
   <value><string>mississippi</string></value>
  </param>
  <param>
   <value><i4>7</i4></value>
  </param>
  <param>
   <value><boolean>0</boolean></value>
  </param>
  <param>
   <value>
    <array><data>
     <value><string>chicken</string></value>
     <value><string>duck</string></value>
     <value><string>goose</string></value>
    </data></array>
   </value>
  </param>
  <param>
   <value>
    <struct>
     <member>
      <name>x</name>
      <value><i4>20</i4></value>
     </member>
     <member>
      <name>y</name>
      <value><string>cow</string></value>
     </member>
     <member>
      <name>z</name>
      <value><double>3.14</double></value>
     </member>
    </struct>
   </value>
  </param>
  <param>
   <value><dateTime.iso8601>20010720T14:48:10</dateTime.iso8601></value>
  </param>
 </params>
</methodCall>
</xmp>
</p>

<a name="rpc-use"></a>
<h2>Making The Procedure Call</h2>
<p>Now that you have the XML message, you need to post it to an RPC server. There are a number of ways to do this. The xmlrpc-socket PHP script allows you to post a message to a remote server and return the response as a JavaScript string to the browser.</p>

<p>Depending upon your implementation, you may need to remove line breaks from, escape or otherwise encode the content of the message before posting it.</p>

<p>The response is also XML-formatted.  Once you receive the response string, you can parse it or load it into a DOM object to walk through its elements.</p>

<a name="rpc-socket"></a>
<h3>Using xmlrpc-socket</h3>

<p>xmlrpc-socket utilizes Brent Ashley's <a href="http://www.ashleyit.com/rs">JavaScript Remote Scripting</a> library to facilitate communication between the browser and the PHP script, and a modified version of Alan van den Bosch's HTTP Post utility to create the POST request from your server to a remote XML-RPC server via PHP.</p>

<p>You can see it in action <a href="test-rs.html">here</a>.</p>

<p>Because xmlrpc-socket serves as a proxy between your browser and the remote RPC server, it helps sidestep JavaScript security in the browser and allow the response to be returned as a JavaScript string.  What you decide to do with this string depends on your web application. xmlrpc-socket strips the header information, leaving only the XML response.</p>

<a name="rpc-download"></a>
<h2>Download</h2>
<p>The download is avaliable as a <a href="xml-rpc.zip">ZIP file</a> (9K) which contains:</p>
<ul>
<li>index.html - this about page.</li>
<li>xmlrpc.js - the XML-RPC message builder script</li>
<li>xmlrpc-socket.php - the PHP proxy</li>
<li>http_post.util - the modifed version of http_post needed by xmlrpc-socket.</li>
<li>all three demo pages</li>
</ul>

<p>You'll also need to grab a copy of the JavaScript Remote Scripting library from <a href="http://www.ashleyit.com/rs">http://www.ashleyit.com/rs</a></p>

<p><a href="mailto:xmlrpc@scottandrew.com">Comments?</a></p>
<p><a href="http://www.scottandrew.com">s c o t t a n d r e w . c o m</a></p>
</body>
</html>
